package com.sumainfor.pc.epc.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sumainfor.common.Constants;
import com.sumainfor.common.entity.MoSupplierObject;
import com.sumainfor.common.exception.TCException;
import com.sumainfor.common.util.*;
import com.sumainfor.common.utlis.ComUtils;
import com.sumainfor.common.utlis.HtmlUtil;
import com.sumainfor.common.utlis.MoSupplierObjectUtil;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.pc.epc.dao.BuyerManageMapper;
import com.sumainfor.pc.epc.dao.SettlementManageMapper;
import com.sumainfor.pc.epc.dao.StockManageMapper;
import com.sumainfor.pc.epc.dao.SupplierManageMapper;
import com.sumainfor.pc.epc.feign.GetUserInfoFeign;
import com.sumainfor.pc.epc.feign.Housingauditfeign;
import com.sumainfor.pc.epc.feign.Zfeign.ZzuulFeign;
import com.sumainfor.pc.epc.service.BuyerManageService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author PuaChen
 * @Create 2018-11-08 14:54
 */
@Service
@Log4j2
@Transactional(rollbackFor = Exception.class)
public class BuyerManageServiceImpl implements BuyerManageService {

    @Autowired
    private BuyerManageMapper buyerManageMapper;

    @Autowired
    private GetUserInfoFeign userInfoFeign;

    @Autowired
    private Housingauditfeign housingauditfeign;

    @Autowired
    private SettlementManageMapper settlementManageMapper;

    @Autowired
    private ComUtils comUtils;

    @Autowired
    private StockManageMapper stockManageMapper;

    @Autowired
    private SupplierManageMapper supplierManageMapper;

    @Autowired
    private ZzuulFeign zzuulFeign;

    /**
     * 获取 装修采购单 或者 备件采购单 列表
     *
     * @param params
     * @param page
     * @return
     */
    @Override
    public JsonResult getBuyerList(Map<String, Object> params, Page page) {
        IPage<Map<String, Object>> list = buyerManageMapper.getBuyerList(page, params);
        for (Map<String, Object> map : list.getRecords()) {
            JsonResult<List<Map<String, Object>>> result = userInfoFeign.getUserInfo(Arrays.asList(MapUtils.getString(map, "SysUserId")));
            if (result.getResult().isEmpty()) {
                continue;
            }
            if (result.isSuccess()) {
                map.put("userName", result.getResult().get(0).get("username"));
                map.put("phone", result.getResult().get(0).get("mobile"));
            }
            //是否显示 采购清单Tab
            if (MapUtils.getIntValue(map, "SaveState", -1) == 0) {
                //已发起了
                map.put("isShowTab2", false);
            } else {
                map.put("isShowTab2", true);
            }

        }
        return JsonResult.success(list);
    }

    /**
     * 获取装修采购中的详细信息中的商品的列表 Tab采购单
     *
     * @param byId 采购单的主ID
     * @return
     */
    @Override
    public JsonResult getBuyerDetailAsZXDone(String byId) {
        List<Map<String, Object>> list = buyerManageMapper.getBuyerDetailAsWxDone(byId, 0);
        if (list.size() != 0) {
            int saveState = MapUtils.getIntValue(list.get(0), "SaveState");
            for (Map<String, Object> map : list) {
                map.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(map, "ComType")));
            }
            if (saveState == 0) {
                //无状态 - 进行供应商分组的操作
                Map<String, List<Integer>> store = Maps.newHashMap();
                for (int i = 0; i < list.size(); i++) {
                    Map<String, Object> map = list.get(i);
                    int count = MapUtils.getIntValue(map, "PutStorage");
                    if (count == 0) {
                        list.remove(i);
                        i--;
                        continue;
                    }
                    BigDecimal price = new BigDecimal(MapUtils.getString(map, "BuyPrice"));
                    BigDecimal differ = price.divide(new BigDecimal(count), 2, BigDecimal.ROUND_HALF_UP);
                    //计算单价
                    map.put("BuySignPrice", differ);

                    if (store.containsKey(map.get("SupId"))) {
                        store.get(map.get("SupId")).add(i);
                    } else {
                        store.put((String) map.get("SupId"), Lists.newArrayList(i));
                    }
                }
                //查询供应商 组装数据
                List<Map<String, Object>> res = Lists.newArrayList();
                for (Map.Entry<String, List<Integer>> entry : store.entrySet()) {
                    Map<String, Object> item = Maps.newHashMap();
                    item.put("SupId", entry.getKey());
                    Map<String, Object> supplier = buyerManageMapper.getSupplierById(entry.getKey());
                    item.put("SupName", MapUtils.getString(supplier, "UnitName"));
                    //组装采购费用
                    BigDecimal sum = new BigDecimal("0.00");
                    // 整体是否采购完成
                    boolean doneState = true;
                    List<Map> data = new ArrayList<>(1);
                    for (Integer index : entry.getValue()) {
                        Map<String, Object> map = list.get(index);
                        if (MapUtils.getIntValue(map, "BuysId") == 1) {
                            doneState = false;
                        }
                        map.remove("supplier");
                        sum = sum.add(new BigDecimal(MapUtils.getString(map, "BuyPrice", "0")));
                        data.add(map);
                    }

                    item.put("sum", sum);
                    item.put("isDoneSuccess", doneState);
                    item.put("data", data);
                    res.add(item);
                }
                return JsonResult.success(res);
            } else {
                //处于保存的状态
                return JsonResult.success(list);
            }
        }
        return JsonResult.error("查询失败");
    }

    /**
     * 获取装修采购中的详细信息中的商品的列表 Tab物品清单
     *
     * @param byId
     * @return
     */
    @Override
    public JsonResult getBuyerDetailAsGoodsList(String byId) {
        List<Map<String, Object>> list = buyerManageMapper.getBuyerDetailAsWxIng(byId);
        //查询是否生成的采购单
        List<Map<String, Object>> info = buyerManageMapper.getBuyerDetailAsWxDone(byId, null);
        if (info.isEmpty()) {
            return JsonResult.success(list.stream().map(item -> {
                item.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(item, "ComType")));
                //已出库数量
                item.put("OutStorage", 0);
                //已采购数量
                item.put("Storage", 0);
                //状态
                item.put("DoneState", false);
                //商品的总库存
                int stockCount = MapUtils.getIntValue(item, "stockCount", 0);
                //商品的需要数量
                int count = MapUtils.getIntValue(item, "countSum", 0);
                if (count <= stockCount) {
                    //库存充足
                    item.put("BuyerCount", 0);
                    item.put("OutCount", count);
                } else {
                    //库存不充足需要进行采购的操作
                    item.put("BuyerCount", count - stockCount);
                    item.put("OutCount", stockCount);
                }
                return item;
            }).collect(Collectors.toList()));
        } else {
            return JsonResult.success(info.stream().filter(item -> MapUtils.getInteger(item, "IfPut") != 1).map(item -> {
                CustomMap map = CustomMap.create();
                map.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(item, "ComType")));
                map.put("ComName", item.get("ComName"));
                map.put("ComSpeName", item.get("ComSpeName"));
                map.put("ComSpeId", item.get("ComSpeId"));
                map.put("ComMonad", item.get("Monad") == null ? stockManageMapper.getMonadBySpeId(MapUtils.getString(item, "ComSpeId")) : item.get("Monad"));
                map.put("countSum", item.get("BuyNumber"));
                map.put("IfOut", item.get("IfOut"));
                map.put("IfPut", item.get("IfPut"));
                map.put("Storage", MapUtils.getIntValue(item, "PutStorageCount", 0));
                map.put("OutStorage", MapUtils.getInteger(item, "OutStorageCount", 0));
                if (MapUtils.getInteger(map, "countSum").equals(MapUtils.getInteger(map, "Storage"))) {
                    map.put("DoneState", true);
                } else if (MapUtils.getInteger(map, "countSum").equals(MapUtils.getInteger(map, "OutStorage"))) {
                    map.put("DoneState", true);
                } else {
                    map.put("DoneState", false);
                }

                //商品的总库存
                Integer stockCount = buyerManageMapper.getStockSum(MapUtils.getString(map, "ComName"), MapUtils.getString(map, "ComSpeName"));
                map.put("stockCount", stockCount);
                map.put("BuyerCount", MapUtils.getInteger(item, "PutStorage", 0));
                map.put("OutCount", MapUtils.getInteger(item, "OutStorage", 0));

                return map;
            }).collect(Collectors.toList()));
        }
    }


    /**
     * 获取装修采购中的详细信息中的商品的列表 Tab出库清单
     *
     * @param buyerId
     * @return
     */
    @Override
    public JsonResult getOutPutStockShopList(String buyerId) {
        List<Map<String, Object>> list = buyerManageMapper.getBuyerDetailAsWxDone(buyerId, 1);
        return JsonResult.success(list.stream().map(item -> {
            //出库状态是否完成
            boolean isDone = false;
            CustomMap append = CustomMap.create();
            if (MapUtils.getInteger(item, "OutStorage").equals(MapUtils.getInteger(item, "OutStorageCount"))) {
                isDone = true;
                //如果采购完成 查询出来商品信息
                List<Map<String, Object>> logs = buyerManageMapper.selectBuyerInfoLog(MapUtils.getInteger(item, "id"));
                BigDecimal sum = new BigDecimal("0.0");
                for (Map<String, Object> v : logs) {
                    sum = sum.add(new BigDecimal(MapUtils.getString(v, "SumPrice")));
                }
                append.put("logs", logs);
                append.put("ComBrand", logs.get(0).get("ComBrand"));
                append.put("ComSpeMoName", logs.get(0).get("ComSpeMoName"));
                append.put("UnitName", logs.get(0).get("UnitName"));
                append.put("SignPrice", Arith.div(MapUtils.getDouble(logs.get(0), "SumPrice"), MapUtils.getDouble(logs.get(0), "ComInventory")));
                append.put("SumPrice", sum);
            }

            Object brandData = this.getBrandList(MapUtils.getString(item, "ComSpeId")).getResult();
            CustomMap data = CustomMap.create("id", item.get("id"))
                    .put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(item, "ComType")))
                    .put("ComName", item.get("ComName"))
                    .put("ComSpeName", item.get("ComSpeName"))
                    .put("Monad", item.get("Monad") != null ? item.get("Monad") : stockManageMapper.getMonadBySpeId(MapUtils.getString(item, "ComSpeId")))
                    .put("isDone", isDone)
                    //获得商品品牌筛选数据列表
                    .put("brandDataList", brandData)
                    .put("OutStorage", item.get("OutStorage"))
                    .put("OutStorageCount", item.get("OutStorageCount"));
            data.putAll(append);
            return data;
        }).collect(Collectors.toList()));
    }

    /**
     * 通过商品名称获得这个所有的商品名称
     *
     * @param speId
     * @return
     */
    @Override
    public JsonResult getBrandList(String speId) {
        return JsonResult.success(buyerManageMapper.getBrandString(speId));
    }


    /**
     * 通过规格的ids 查询所有的型号信息
     *
     * @param ids
     * @return
     */
    @Override
    public JsonResult getTypeByComIds(List<String> ids) {
        return JsonResult.success(buyerManageMapper.getTypeByComIds(ids).stream().map(item -> {
            item.put("supplier", MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(item, "supplier")).stream().map(su -> {
                CustomMap map = ObjectUtil.convertObjectToMap(su);
                map.put("UnitName", supplierManageMapper.getSupplierOne(su.getSupplierId()).get("UnitName"));
                return map;
            }).collect(Collectors.toList()));
            return item;
        }).collect(Collectors.toList()));
    }

    /**
     * 装修计划才有的
     * 查询出来 这个商品的所属房源列表的详细信息
     *
     * @param speId
     * @param buyId
     * @return
     */
    @Override
    public JsonResult getShopRelateHousingForZx(String speId, String buyId) {
        List<Map<String, Object>> list = buyerManageMapper.getShopRelateHousingForZx(speId, buyId);
        List<String> ids = Lists.newArrayList();
        for (Map<String, Object> map : list) {
            ids.add(MapUtils.getString(map, "HouId"));
        }
        //1. 发起请求 获取更加详细的信息
        JsonResult<List<Map<String, Object>>> result = housingauditfeign.getProjectNameAndHousingConf(ids);
        if (!result.isSuccess()) {
            return result;
        }
        //2.数据组装的操作
        for (Map<String, Object> map : list) {
            for (Map<String, Object> resMap : result.getResult()) {
                if (MapUtils.getString(map, "HouId").equals(MapUtils.getString(resMap, "HouId"))) {
                    map.putAll(resMap);
                    break;
                }
            }
        }
        return JsonResult.success(list);
    }

    /**
     * 查看采购清单 Tab采购清单
     *
     * @param buyerId
     * @return
     */
    @Override
    public JsonResult getNotBuyerOrderInfo(String buyerId) {
        List<Map<String, Object>> buyerInfo = buyerManageMapper.selectBuyerOrderTab(buyerId);
        buyerInfo = buyerInfo.stream().map(item -> {
            item.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(item, "ComType")));
            item.remove("IfOut");
            item.remove("OutStorage");
            item.remove("OutStorageCount");
            if (StringUtils.isBlank(MapUtils.getString(item, "Monad"))) {
                item.put("Monad", stockManageMapper.getMonadBySpeId(MapUtils.getString(item, "ComSpeId")));
            }
            item.put("BrandList", getBrandList(MapUtils.getString(item, "ComSpeId")).getResult());
            return item;
        }).collect(Collectors.toList());

        return JsonResult.success(buyerInfo);
    }


    /**
     * 创建采购单以及出库清单 第一步
     *
     * @param buyerId
     * @return
     */
    @Override
    public JsonResult createBuyerAndOutForOrder(String buyerId) {
        Map<String, Object> buyerMain = buyerManageMapper.getBuyerMainById(buyerId);
        if (MapUtils.isEmpty(buyerMain)) {
            return JsonResult.error("没有这个采购单");
        }
        if (MapUtils.getInteger(buyerMain, "SaveState") != null) {
            return JsonResult.error("这个采购单已经生成了采购单和出库清单了");
        }

        //获得 需要生成的商品列表
        List<Map<String, Object>> list = (List<Map<String, Object>>) this.getBuyerDetailAsGoodsList(buyerId).getResult();
        if (list.isEmpty()) {
            return JsonResult.error("没有商品");
        }

        boolean isAllOut = false;

        //构造数据添加商品的操作
        for (Map<String, Object> map : list) {
            int ifOut = 0;
            if (MapUtils.getIntValue(map, "OutCount", 0) > 0) {
                ifOut = 1;
            } else {
                isAllOut = true;
            }
            String comId = buyerManageMapper.getShopIdByShopName(MapUtils.getString(map, "ComName"));
            CustomMap data = CustomMap.create("BuyId", buyerId)
                    .put("ComId", comId)
                    .put("ComSpeId", MapUtils.getString(map, "ComSpeId"))
                    .put("BuyNumber", MapUtils.getString(map, "countSum"))
                    .put("BuyNumber", MapUtils.getInteger(map, "countSum"))
                    .put("Storage", 0)
                    .put("OutStorage", MapUtils.getInteger(map, "OutCount", 0))
                    .put("OutStorageCount", 0)
                    .put("PutStorage", MapUtils.getInteger(map, "BuyerCount", 0))
                    .put("PutStorageCount", 0)
                    .put("BuyPrice", 0)
                    .put("IfOut", ifOut)
                    .put("IfPut", 0)
                    .put("BuysId", 1);
            ParamsCommon.commonInsertParms(data, getClass());
            int row = buyerManageMapper.insertBuyerInfo(data);
            if (row <= 0) {
                throw new TCException("插入数据出错");
            }
        }

        if (!isAllOut) {
            //更新主表为采购中 前提是 只有出库没有采购状态
            //更新主表信息
            int row = buyerManageMapper.updateBuyerMain(ParamsCommon.commonUpdateParms(
                    CustomMap.create("BuyId", buyerId)
                            .put("SaveState", 0)
                            .put("IfBuyer", 1)
                            .put("BuyState", 2)
                    , getClass()));
            if (row <= 0) {
                throw new TCException("更新主表失败");
            }
        } else {
            int row = buyerManageMapper.updateBuyerMain(ParamsCommon.commonUpdateParms(
                    CustomMap.create("BuyId", buyerId)
                            .put("SaveState", 0)
                    , getClass()));
            if (row <= 0) {
                throw new TCException("更新主表失败");
            }
        }

        return JsonResult.success("成功");
    }


    /**
     * 创建装修采购单
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult createBuyerOrder(Map<String, Object> params) {
        //获得类型 1 为普通保存  0. 为生成采购单
        int isType = MapUtils.getInteger(params, "type");
        //主表的编号
        String buyId = MapUtils.getString(params, "BuyId");
        List<Map<String, Object>> dataList = (List<Map<String, Object>>) MapUtils.getObject(params, "dataList");
        if (dataList == null || dataList.isEmpty()) {
            return JsonResult.error("参数错误");
        }

        //更新主表信息
        int row = buyerManageMapper.updateBuyerMain(ParamsCommon.commonUpdateParms(
                CustomMap.create("BuyId", buyId)
                        .put("SaveState", isType)
                        .put("IfBuyer", 0)
                        .put("BuyState", isType == 0 ? 2 : 1)
                , getClass()));
        if (row <= 0) {
            return JsonResult.error("创建失败");
        }

        //更新详表数据开始
        for (Map<String, Object> map : dataList) {
            if (!FieldCheckUtil.isMapFieldNotNull(map, "id", "ComId", "ComSpeId", "ComSpeMoId", "SupId")) {
                throw new TCException("缺少必要的参数");
            }
            //查询详情表的数据
            Map<String, Object> infoMap = buyerManageMapper.selectBuyerInfoById(MapUtils.getString(map, "id"));
            if (MapUtils.isEmpty(infoMap)) {
                throw new TCException("没有查询到这个详情数据");
            }
            //查询型号

            Map<String, Object> moMap = stockManageMapper.getShopMoForInfos(MapUtils.getString(map, "ComSpeMoId"));
            if (MapUtils.isEmpty(moMap)) {
                throw new TCException("没有查询到这个型号数据");
            }
            List<MoSupplierObject> moSupList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moMap, "supplier"));
            MoSupplierObject moSup = MoSupplierObjectUtil.selectSupplierById(moSupList, MapUtils.getString(map, "SupId"));
            if (moSup == null) {
                throw new TCException("没有查询到这个供应商");
            }

            //需要采购的数量
            int buyerCount = MapUtils.getIntValue(infoMap, "PutStorage");
            //计算需要采购的总价
            BigDecimal sum = moSup.getPrice().multiply(new BigDecimal(buyerCount));

            //判断是入库插入新数据还是说更新数据 凑单需要的参数  IfPut  PutNumber
            if (StringUtils.isBlank(MapUtils.getString(map, "IfPut")) && MapUtils.getIntValue(map, "IfPut") != 1) {
                //构建数据进行更新的操作
                row = buyerManageMapper.updateBuyerInfo(ParamsCommon.commonUpdateParms(CustomMap.create("id", MapUtils.getString(map, "id"))
                                .put("BuyId", buyId)
                                .put("ComId", MapUtils.getString(map, "ComId"))
                                .put("ComSpeId", MapUtils.getString(map, "ComSpeId"))
                                .put("ComSpeMoId", MapUtils.getString(map, "ComSpeMoId"))
                                .put("SupId", MapUtils.getString(map, "SupId"))
                                .put("BuyPrice", sum)
                                .put("BuysId", 1)
                        , getClass()));
                if (row <= 0) {
                    throw new TCException("创建采购单失败!");
                }
            } else {
                if (!FieldCheckUtil.isMapFieldNotNull(map, "PutNumber", "IfPut")) {
                    throw new TCException("凑单参数不完整");
                }

                sum = moSup.getPrice().multiply(new BigDecimal(MapUtils.getString(map, "PutNumber")));

                //是需要入库的凑单进行 插入的操作
                CustomMap inData = CustomMap.create();
                inData.putAll(infoMap);
                inData.remove("id");
                inData.put("IfOut", 0);
                inData.put("IfPut", 1);
                inData.put("OutStorage", 0);
                inData.put("OutStorageCount", 0);
                inData.put("BuyNumber", map.get("PutNumber"));
                inData.put("PutNumber", map.get("PutNumber"));
                inData.put("PutStorage", map.get("PutNumber"));
                inData.put("PutStorageCount", 0);
                inData.put("ComId", MapUtils.getString(map, "ComId"))
                        .put("ComSpeId", MapUtils.getString(map, "ComSpeId"))
                        .put("ComSpeMoId", MapUtils.getString(map, "ComSpeMoId"))
                        .put("SupId", MapUtils.getString(map, "SupId"))
                        .put("BuyPrice", sum)
                        .put("BuysId", 1);
                row = buyerManageMapper.insertBuyerInfo(ParamsCommon.commonInsertParms(inData, getClass()));
                if (row <= 0) {
                    throw new TCException("创建采购单凑单失败!");
                }
            }
        }

        //生成结算单主表  只针对装修采购单使用的
        if (isType == 0) {
            //计算总价格
            BigDecimal priceSum = buyerManageMapper.getBuyerInfoSumPrice(buyId);

            String staId = comUtils.getLocalTrmSeqNumByLook("Sta", Constants.DATA_SOURCE_TCEPC, "tcepc_statement", "StaId");
            int i = settlementManageMapper.insertStaMain(ParamsCommon.commonInsertParms(CustomMap.create("StaId", staId)
                    .put("StaType", 0)
                    .put("StaCut", 1)
                    .put("SourceId", buyId)
                    //已付金额
                    .put("PaidPrices", 0)
                    .put("CopeWithPrices", priceSum)
                    .put("UnpaidPrices", priceSum), getClass()));
            if (i <= 0) {
                throw new TCException("生成结算单失败");
            }
            //去生成结算单详表记录
            boolean success = createStaInfo(buyId);
            if (!success) {
                throw new TCException("生成结算单详表失败");
            }
        }
        return JsonResult.success("创建成功");
    }

    /**
     * 更新采购单详细表的 状态为采购完成 和 如果全部完成 更新主表
     * 针对装修采购单的
     *
     * @param ids   详表的ID 集合
     * @param buyId 采购单的ID
     * @return
     */
    @Override
    public JsonResult setBuyerInfoStateForDone(List<Integer> ids, String buyId) {

        buyerManageMapper.updateBuyerInfoStateForDone(ids);

        //查询所有的需要入库的列表信息
        //是否需要入库：只针对装修采购
        //0不需要入库     1需要入库
        List<Map<String, Object>> data = buyerManageMapper.selectBuyerInfoZxForPutStoreData(ids);
        if (!data.isEmpty()) {
            this.putStore(data.stream().map(item -> CustomMap.create("id", item.get("id"))
                    .put("count", item.get("BuyNumber"))
                    .put("buyId", item.get("BuyId"))
                    .put("moId", item.get("ComSpeMoId"))).collect(Collectors.toList()));
        }


        //查询 全部详表状态是否全部采购完成 及时更新主表中的状态信息
        int count = buyerManageMapper.selectUnDoneCount(buyId);
        if (count == 0) {
            buyerManageMapper.updateBuyerMain(CustomMap.create("BuyId", buyId)
                    .put("BuyState", 3));
            Map<String, Object> buyerMain = buyerManageMapper.getBuyerMainByBuyerId(buyId);
            if (MapUtils.isEmpty(buyerMain)) {
                throw new TCException("获取来源编号失败");
            }
            this.updateHousingConfig(buyerMain);
        }


        return JsonResult.success("操作成功");
    }


    /**
     * 装修采购的 出库商品的操作
     *
     * @param data  [
     *              {
     *              "id":1,   //id
     *              "count":5  // 出库的数量
     *              }
     *              ]
     * @param buyId
     * @return
     */
    @Override
    public JsonResult buyerOutAction(List<Map<String, Object>> data, String buyId) {
        for (int i = 0; i < data.size(); i++) {
            Map<String, Object> item = data.get(i);
            if (!FieldCheckUtil.isMapFieldNotNull(item, "id", "count", "ComSpeMoId", "SupId", "ComId", "ComSpeId")) {
                throw new TCException("参数不完整");
            }
            int id = MapUtils.getIntValue(item, "id");
            int count = MapUtils.getIntValue(item, "count");
            String moId = MapUtils.getString(item, "ComSpeMoId");
            String supId = MapUtils.getString(item, "SupId");
            String comId = MapUtils.getString(item, "ComId");
            String speId = MapUtils.getString(item, "ComSpeId");

            Map<String, Object> info = buyerManageMapper.selectBuyerInfoById(id + "");
            if (MapUtils.isEmpty(info)) {
                throw new TCException("没有查询到这条记录");
            }
            int sum = MapUtils.getIntValue(info, "OutStorage");
            int doneCount = MapUtils.getIntValue(info, "OutStorageCount");
            boolean isDoneState = false;
            if (sum == doneCount || sum < (doneCount + count)) {
                throw new TCException("出库数量异常");
            }

            if ((doneCount + count) == sum) {
                isDoneState = true;
            }

            int row = buyerManageMapper.updateBuyerInfoOutShop(id, count, buyId, isDoneState, comId, speId, moId, supId);
            if (row <= 0) {
                throw new TCException("出库失败:" + id);
            }
            //查询是否有为没有采购成功的条目
            //查询 全部详表状态是否全部采购完成 及时更新主表中的状态信息
            int unCount = buyerManageMapper.selectUnDoneCount(buyId);
            if (unCount == 0) {
                buyerManageMapper.updateBuyerMain(CustomMap.create("BuyId", buyId)
                        .put("BuyState", 3));
                Map<String, Object> buyerMain = buyerManageMapper.getBuyerMainByBuyerId(MapUtils.getString(info, "BuyId"));
                if (MapUtils.isEmpty(buyerMain)) {
                    throw new TCException("获取来源编号失败");
                }
                this.updateHousingConfig(buyerMain);
            }

            //进行出库之后减少 库存数量
            Map<String, Object> moData = buyerManageMapper.selectComMoOne(moId);
            if (moData == null) {
                throw new TCException("出库异常,商品型号不存在");
            }
            List<MoSupplierObject> moSupplierList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moData, "supplier"));
            if (moSupplierList.isEmpty()) {
                throw new TCException("出库异常,商品型号没有供应商列表");
            }
            MoSupplierObject moSupplierObject = MoSupplierObjectUtil.selectSupplierById(moSupplierList, supId);
            if (moSupplierObject == null) {
                throw new TCException("出库异常,没有这个供应商");
            }
            //原库存数
            int oldCount = moSupplierObject.getStoreCount();
            moSupplierObject.subStoreCount(count);
            //更新型号表信息
            row = buyerManageMapper.updateShopForMo(ParamsCommon.commonUpdateParms(CustomMap.create("ComSpeMoId", moId)
                            .put("supplier", MoSupplierObjectUtil.toJson(moSupplierList))
                            .put("Stock", MapUtils.getInteger(moData, "Stock") - count)
                    , getClass()));
            if (row <= 0) {
                throw new TCException("更新商品出库数量,操作失败");
            }
            //现在的库存数
            int currentCount = moSupplierObject.getStoreCount();
            //添加备件出库的记录
            //1.构建数据参数
            CustomMap logOutMap = CustomMap.create("ComOutId", UUIDUtils.generatePrefixUuid("OutLog"))
                    .put("ComOutType", 2)
                    .put("SysUserId", ContextUtils.getUserId())
                    .put("ComSpeMoId", moId)
                    .put("SupId", supId)
                    //原来库存数量
                    .put("RawInventory", oldCount)
                    //出库存数量
                    .put("ComInventory", count)
                    //现在库存数量
                    .put("CasInventory", currentCount);
            ParamsCommon.commonInsertParms(logOutMap, getClass());
            //2. 数据库插入
            row = stockManageMapper.insertStockMainWriteOutLog(logOutMap);
            if (row <= 0) {
                throw new TCException("创建备件出库记录失败");
            }

            //构建装修采购单详表出库记录
            row = buyerManageMapper.insertBuyerInfoLog(ParamsCommon.commonInsertParms(CustomMap.create()
                            .put("BuyInfoId", id)
                            .put("ComId", comId)
                            .put("ComSpeId", speId)
                            .put("ComSpeMoId", moId)
                            .put("SupId", supId)
                            .put("RawInventory ", oldCount)
                            .put("ComInventory", count)
                            .put("CasInventory", currentCount)
                            .put("SumPrice", moSupplierObject.getPrice().multiply(new BigDecimal(count)))
                    , getClass()));
            if (row <= 0) {
                throw new TCException("插入采购出库记录失败");
            }
        }
        return JsonResult.success("成功");
    }

    /**
     * 更新房源配置
     *
     * @param params
     */
    private void updateHousingConfig(Map<String, Object> params) {
        if (MapUtils.isEmpty(params)) {
            throw new TCException("参数异常");
        }

        List<Map<String, Object>> infoList = buyerManageMapper.selectBuyerInfoList(MapUtils.getString(params, "BuyId"));

        List<Map<String, Object>> list = buyerManageMapper.selectHousingConfigList(MapUtils.getString(params, "SourceId"));
        for (int i = 0; i < list.size(); i++) {
            //房源配置数据
            Map<String, Object> map = list.get(i);
            for (int i1 = 0; i1 < infoList.size(); i1++) {
                //采购单详表数据
                Map<String, Object> info = infoList.get(i1);
                //转化后的商品数据
                Map<String, Object> shopInfo = stockManageMapper.getShopMoForInfos(MapUtils.getString(info, "ComSpeMoId"));
                //判断比对
                if (Objects.equals(MapUtils.getString(map, "ComName"), MapUtils.getString(shopInfo, "ComName"))
                        && Objects.equals(MapUtils.getString(map, "ComSpeName"), MapUtils.getString(shopInfo, "ComSpeName"))) {

                    //取出商品的单价
                    List<MoSupplierObject> moSupList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(shopInfo, "supplier"));
                    MoSupplierObject moSupObj = MoSupplierObjectUtil.selectSupplierById(moSupList, MapUtils.getString(info, "SupId"));
                    if (moSupObj == null) {
                        throw new TCException("没有找对这个商品对应的供应商信息");
                    }


                    //成立 更新房源配置信息
                    int row = buyerManageMapper.updateHousingConfig(ParamsCommon.commonUpdateParms(CustomMap.create("id", map.get("id"))
                                    .put("ComId", shopInfo.get("ComId"))
                                    .put("ComName", shopInfo.get("ComName"))
                                    .put("SupId", info.get("SupId"))
                                    .put("ComSpeName", shopInfo.get("ComSpeName"))
                                    .put("ComSpeId", shopInfo.get("ComSpeId"))
                                    .put("ComSpeMoId", shopInfo.get("ComSpeMoId"))
                                    .put("ComSpeMoName", shopInfo.get("ComSpeMoName"))
                                    .put("ComMonad", shopInfo.get("Monad"))
                                    .put("ComPrice", moSupObj.getPrice())
                            , getClass()));
                    if (row <= 0) {
                        throw new TCException("更新房源配置信息失败!");
                    }
                }
            }
        }
    }


    /**
     * 创建备件采购单
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult createStandbyOrder(Map<String, Object> params) {
        List<Map<String, Object>> dataList = (List<Map<String, Object>>) params.get("dataList");
        if (dataList == null || dataList.isEmpty()) {
            return JsonResult.error("参数错误");
        }

        String uuid = comUtils.getLocalTrmSeqNumByLook("Buyer", Constants.DATA_SOURCE_TCEPC, "tcepc_buyer", "BuyId");

        //获取的所属公司编号
        Integer areaId = ContextUtils.getSysUser().getAreaId();

        //构建备件采购单主表数据
        CustomMap mainMap = CustomMap.create("SysUserId", ContextUtils.getUserId())
                .put("BuyState", 4)
                .put("CorId", areaId)
                .put("Explain", MapUtils.getString(params, "Explain"))
                .put("BuyType", 2)
                .put("BuyId", uuid);
        ParamsCommon.commonInsertParms(mainMap, getClass());
        int row = buyerManageMapper.insertBuyerStandbyMain(mainMap);
        if (row <= 0) {
            return JsonResult.error("创建失败");
        }

        //添加数据开始
        for (Map<String, Object> map : dataList) {
            String[] fields = {"ComId", "ComSpeId", "ComSpeMoId", "BuyNumber", "SupId"};
            if (!FieldCheckUtil.isMapFieldNotNull(map, fields)) {
                throw new TCException("参数不完整");
            }

            String speId = MapUtils.getString(map, "ComSpeId");
            String comId = MapUtils.getString(map, "ComId");
            String moId = MapUtils.getString(map, "ComSpeMoId");
            String supId = MapUtils.getString(map, "SupId");
            Integer count = MapUtils.getInteger(map, "BuyNumber");

            //查询型号
            Map<String, Object> moInfo = buyerManageMapper.getShopMoForNumber(comId, speId, moId);
            if (MapUtils.isEmpty(moInfo)) {
                throw new TCException("没有查询到这个商品信息");
            }
            //查询供应商
            List<MoSupplierObject> moSupList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moInfo, "supplier"));
            if (moSupList.isEmpty()) {
                throw new TCException("商品没有绑定任何的供应商");
            }
            MoSupplierObject moSupObj = MoSupplierObjectUtil.selectSupplierById(moSupList, supId);
            if (moSupObj == null) {
                throw new TCException("商品没有绑定这个供应商");
            }

            //计算总价
            BigDecimal sumPrice = moSupObj.getPrice().multiply(new BigDecimal(count));


            map.put("BuyId", uuid);

            row = buyerManageMapper.insertBuyerInfo(ParamsCommon.commonInsertParms(CustomMap.converToCustomMap(map)
                            .put("BuyPrice", sumPrice)
                            .put("BuysId", 1)
                            .put("Storage", 0)
                            .remove("delfg")
                    , getClass()));
            if (row <= 0) {
                throw new TCException("创建备件采购单失败");
            }
        }

        //通知
        CustomMap data = CustomMap.create("MeType", 5)
                .put("Title", "待审核备件采购单")
                .put("Content", HtmlUtil.stringToHTML("您有新的备件采购单需审核，请及时处理", "", Color.blue))
                .put("by", ContextUtils.getUserId())
                .put("IfJump", 1)
                .put("Neturl", "/sys-engineeringmanager/buyer")
                .put("term", 3);
        zzuulFeign.AddMessage(data);
        return JsonResult.success("创建成功");
    }

    /**
     * 撤回备件采购单
     * 功能：
     * 删除备件采购单
     *
     * @return
     */
    @Override
    public JsonResult withdrawStandbyOrder(String buyId) {
        int row = buyerManageMapper.withdrawStandbyOrder(buyId);
        return row <= 0 ? JsonResult.error("撤回失败") : JsonResult.success("操作成功");
    }


    /**
     * 获取备件采购单  采购中的账单详情
     *
     * @param buyId
     * @return
     */
    @Override
    public JsonResult getStandbyInfo(String buyId) {
        List<Map<String, Object>> data = buyerManageMapper.getBuyerDetailAsWxDone(buyId, null);
        BigDecimal bigDecimal = new BigDecimal("0.0");
        int ingCount = 0;
        for (Map<String, Object> map : data) {
            bigDecimal = bigDecimal.add(new BigDecimal(MapUtils.getString(map, "BuyPrice")));
            int count = MapUtils.getIntValue(map, "BuyNumber");
            int currentCount = MapUtils.getIntValue(map, "Storage");
            if (count != currentCount) {
                ingCount++;
            }
            //需要的入库数量
            map.put("wantCount", count - currentCount);
            map.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(map, "ComType")));
        }
        return JsonResult.success(CustomMap.create("allPrice", bigDecimal)
                .put("count", data.size())
                .put("ingCount", ingCount)
                .put("list", data));
    }


    /**
     * 进行入库的操作,不修改采购单的主表
     * 入参：
     * 采购详情标的ID
     * 入库的数量
     * 采购单主表的编号
     * 型号的编号
     *
     * @param list
     * @return
     */
    @Override
    public JsonResult putStore(List<Map<String, Object>> list) {
        for (Map<String, Object> map : list) {
            String id = MapUtils.getString(map, "id");
            Integer count = MapUtils.getInteger(map, "count");
            String buyId = MapUtils.getString(map, "buyId");
            int oldStoreCount;
            int currentStoreCount;
            if (StringUtils.isBlank(id) || StringUtils.isBlank(buyId) || count == null) {
                throw new TCException("参数错误,操作失败");
            }
            //先查询是否已经完成
            Map<String, Object> infOld = buyerManageMapper.selectBuyerInfoById(id);
            if (infOld.isEmpty()) {
                continue;
            }

            String moId = MapUtils.getString(infOld, "ComSpeMoId");
            String supId = MapUtils.getString(infOld, "SupId");

            int buyNumber = MapUtils.getIntValue(infOld, "BuyNumber");
            int storage = MapUtils.getIntValue(infOld, "Storage");
            int state = 1;
            if (buyNumber == storage) {
                continue;
            }

            if ((storage + count) > buyNumber) {
                throw new TCException("入库数量不可以超过商品总需要数量");
            } else if ((storage + count) == buyNumber) {
                //设置为已采购
                state = 2;
            }
            //更新详表的信息数据
            int row = buyerManageMapper.updateBuyerInfo(CustomMap.create("BuyId", buyId)
                    .put("id", id)
                    .put("BuysId", state)
                    .put("Storage", storage + count)
                    .put("BuyId", buyId));
            if (row <= 0) {
                throw new TCException("入库出现异常,操作失败");
            } else {
                //判断是否是处于完成采购这一个商品的状态并且还是备件采购单，然后进行查询修改主表
                if (state == 2 && Objects.equals(MapUtils.getInteger(infOld, "BuyType"), 2)) {
                    //生成结算单详表前提是备件采购单
                    //查询 全部详表状态是否全部采购完成 及时更新主表中的状态信息
                    int cun = buyerManageMapper.selectUnDoneCount(buyId);
                    if (cun == 0) {
                        buyerManageMapper.updateBuyerMain(CustomMap.create("BuyId", buyId)
                                .put("BuyState", 3));
                    }
                }

                //入库成功 将其添加到商品的库存里去
                //1. 查询这个型号
                Map<String, Object> mo = buyerManageMapper.selectComMoOne(moId);
                if (!FieldCheckUtil.isMapFieldNotNull(mo, "supplier")) {
                    //为空 变为新增
                    throw new TCException("此商品不存在");
                } else {
                    //更新
                    List<MoSupplierObject> supplier = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(mo, "supplier"));
                    MoSupplierObject object = MoSupplierObjectUtil.selectSupplierById(supplier, supId);
                    if (object == null) {
                        throw new TCException("此商品供应商不存在");
                    }
                    //原库存数
                    oldStoreCount = object.getStoreCount();
                    object.addStoreCount(count);
                    //更新后的库存数
                    currentStoreCount = object.getStoreCount();
                    //更新主表的总库存数量
                    mo.put("Stock", MapUtils.getInteger(mo, "Stock") + count);
                    mo.put("supplier", MoSupplierObjectUtil.toJson(supplier));
                    row = buyerManageMapper.updateShopForMo(mo);
                    if (row <= 0) {
                        throw new TCException("商品入库出现异常,操作失败");
                    }
                }

                // 添加备件入库的操作记录
                //获得UUID
                //String uuid = comUtils.getLocalTrmSeqNumByLook("StockInLog", Constants.DATA_SOURCE_TCEPC, "tcepc_commodity_in", "ComInId");
                String uuid = UUIDUtils.generatePrefixUuid("StockInLog");
                CustomMap logData = CustomMap.create("ComInId", uuid)
                        .put("BuyId", buyId)
                        .put("ComSpeMoId", moId)
                        .put("SupId", infOld.get("SupId"))
                        .put("RawInventory", oldStoreCount)
                        .put("ComInventory", count)
                        .put("CasInventory", currentStoreCount);
                ParamsCommon.commonInsertParms(logData, getClass());
                row = buyerManageMapper.insertStoreInPutLog(logData);
                if (row <= 0) {
                    throw new TCException("商品入库添加日志出现异常,操作失败");
                }
            }
        }
        return JsonResult.success("操作成功");
    }

    /**
     * 生成结算单详表
     *
     * @param buyerId 采购单主表ID
     * @return true 成功 false 失败
     */
    public boolean createStaInfo(String buyerId) {
        //查询结算单的主表数据
        Map<String, Object> staMain = settlementManageMapper.getStaMainByBuyerId(buyerId);
        if (staMain == null || staMain.isEmpty()) {
            throw new TCException("操作失败,结算单主表尚未创建");
        }

        //查询采购单详表数据
        List<Map<String, Object>> infoList = buyerManageMapper.selectBuyerInfoForCreateSettment(buyerId);
        if (CollectionUtils.isEmpty(infoList)) {
            throw new TCException("操作失败,没有查询到采购单采购信息");
        }

        for (Map<String, Object> infoMap : infoList) {
            String staInfoId = comUtils.getLocalTrmSeqNumByLook("StaInfo", Constants.DATA_SOURCE_TCEPC, "tcepc_statement_info", "StasId");
            //构建数据
            Map<String, Object> data = ParamsCommon.commonInsertParms(CustomMap.create("StasId", staInfoId)
                            .put("StaId", MapUtils.getString(staMain, "StaId"))
                            .put("SupId", MapUtils.getString(infoMap, "SupId"))
                            .put("CopeWithPrice", MapUtils.getString(infoMap, "BuyPrice"))
                            .put("PaidPrice", 0)
                            .put("UnpaidPrice", MapUtils.getString(infoMap, "BuyPrice"))
                            .put("State", 0)
                            .put("StaState", 1)
                    , getClass());
            int row = settlementManageMapper.insertStaInfoData(data);
            if (row <= 0) {
                throw new TCException("生成结算单失败");
            }
        }

        return true;
    }

}
